package cn.lczze.stock.service.impl;

import cn.lczze.stock.enums.FieldCodeEnum;
import cn.lczze.stock.enums.ProfitAndLossEnum;
import cn.lczze.stock.mapper.base.StockBaseMapper;
import cn.lczze.stock.mapper.base.StockInfoMapper;
import cn.lczze.stock.model.base.StockBaseModel;
import cn.lczze.stock.model.base.StockInfo;
import cn.lczze.stock.service.StockBaseService;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class StockBaseImpl implements StockBaseService {

    @Autowired
    private StockInfoMapper stockInfoMapper;




    @Override
    public List<JSONObject> profitLimitList() {
        List<JSONObject> list = new ArrayList<>();
        List<StockInfo> stockInfos = stockInfoMapper.selectAll();
        if (stockInfos == null || stockInfos.size() <= 0){
            log.error("未查到股票基础数据列表");
            return list;
        }
        stockInfos = stockInfos.stream().filter(p -> p.getContinueDay() > 0).collect(Collectors.toList());
        Map<Integer, List<StockInfo>> continueDayMap = new HashMap<>();
        for (StockInfo stockInfoModel : stockInfos) {
            if (stockInfoModel.getProfitAndLoss() == null || stockInfoModel.getProfitAndLoss().equals(ProfitAndLossEnum.LOSS.getCode())){
                continue;
            }
            if (stockInfoModel.getContinueDay() == 0 || stockInfoModel.getContinueDay() <= 1){
                continue;
            }
            if (continueDayMap.containsKey(stockInfoModel.getContinueDay())) {
                List<StockInfo> stockBaseModelDayList = continueDayMap.get(stockInfoModel.getContinueDay());
                stockBaseModelDayList.add(stockInfoModel);;
                continueDayMap.put(stockInfoModel.getContinueDay(), stockBaseModelDayList);
            }else {
                continueDayMap.put(stockInfoModel.getContinueDay(), Lists.newArrayList(stockInfoModel));
            }
        }
        if (continueDayMap == null || continueDayMap.size() <= 0){
            return list;
        }
        Set<Integer> continueDaySet = continueDayMap.keySet();
        List<Integer> continueDaySortList = continueDaySet.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        int j = 1;
        for (Integer day : continueDaySortList) {
            JSONObject dayJson = new JSONObject();
            dayJson.put("continueDay", day + "连板");
            dayJson.put("children", convertJsonObject(continueDayMap.get(day), j));
            dayJson.put("id", day + 10000);
//            dayJson.put("name", "");
//            dayJson.put("price", "");
            list.add(dayJson);
            j ++;
        }


        JSONObject dayJson1 = new JSONObject();
        dayJson1.put("continueDay", " ");
        dayJson1.put("children", "");
        dayJson1.put("id", 1 + 100000);

        return list;
    }

    @Override
    public List<JSONObject> lossLimitList() {
        List<JSONObject> list = new ArrayList<>();
        List<StockInfo> stockInfos = stockInfoMapper.selectAll();
        if (stockInfos == null || stockInfos.size() <= 0){
            log.error("未查到股票基础数据列表");
            return list;
        }
        Map<Integer, List<StockInfo>> continueDayMap = new HashMap<>();
        for (StockInfo stockInfoModel : stockInfos) {
            if (stockInfoModel.getProfitAndLoss() == null || stockInfoModel.getProfitAndLoss().equals(ProfitAndLossEnum.PROFIT.getCode())){
                continue;
            }
            if (stockInfoModel.getContinueDay() == 0 || stockInfoModel.getContinueDay() <= 1){
                continue;
            }
            if (continueDayMap.containsKey(stockInfoModel.getContinueDay())) {
                List<StockInfo> stockBaseModelDayList = continueDayMap.get(stockInfoModel.getContinueDay());
                stockBaseModelDayList.add(stockInfoModel);
                continueDayMap.put(stockInfoModel.getContinueDay(), stockBaseModelDayList);
            }else {
                continueDayMap.put(stockInfoModel.getContinueDay(), Lists.newArrayList(stockInfoModel));
            }
        }
        if (continueDayMap == null || continueDayMap.size() <= 0){
            return list;
        }
        Set<Integer> continueDaySet = continueDayMap.keySet();
        List<Integer> continueDaySortList = continueDaySet.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        int j = 1;
        for (Integer day : continueDaySortList) {
            JSONObject dayJson = new JSONObject();
            dayJson.put("continueDay", day + "连板");
            dayJson.put("children", convertJsonObject(continueDayMap.get(day), j));
            dayJson.put("id", day + 10000);
//            dayJson.put("name", "");
//            dayJson.put("price", "");
            list.add(dayJson);
            j++;
        }
        return list;
    }

    private List<JSONObject> convertJsonObject(List<StockInfo> dayStockList,Integer j){
        List<JSONObject> list = new ArrayList<>();
        if (dayStockList == null || dayStockList.size() <= 0) {
           return list;
        }
        int i = 1;
        for (StockInfo stockInfo : dayStockList) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", j + i);
            jsonObject.put("name", stockInfo.getName());
            jsonObject.put("ticker", stockInfo.getTsCode());
            jsonObject.put("price", stockInfo.getPrice());
            jsonObject.put("ts_code", stockInfo.getTsCode());

            jsonObject.put("open", stockInfo.getOpen());
            jsonObject.put("high", stockInfo.getHigh());
            jsonObject.put("low", stockInfo.getLow());
            jsonObject.put("close", stockInfo.getPrice());
            jsonObject.put("pre_close", stockInfo.getPreClose());
            jsonObject.put("change", stockInfo.getChange());
            jsonObject.put("pct_chg", stockInfo.getPctChg());
            jsonObject.put("vol", stockInfo.getVol());
            jsonObject.put("amount", stockInfo.getAmount());
            jsonObject.put("market", stockInfo.getMarket());
            jsonObject.put("industry", stockInfo.getIndustry());
            list.add(jsonObject);
            i++;
        }
        return list;
    }

    @Override
    public List<StockInfo> volSort() {
        List<StockInfo> stockInfos = stockInfoMapper.selectAll();
        if (stockInfos == null || stockInfos.size() <= 0){
            log.error("未查到股票基础数据列表");
            return new ArrayList<>();
        }
        stockInfos = stockInfos.stream()
                .filter(p -> p.getVol() != null && !p.getAmount().isEmpty())
                .filter(p -> {
                    try {
                        Double.parseDouble(p.getVol());
                        return true;
                    } catch (NumberFormatException e) {
                        return false;
                    }
                })
                .sorted(Comparator.comparingDouble(
                        (StockInfo p) -> Double.parseDouble(p.getVol())).reversed()
                )
                .limit(30)
                .collect(Collectors.toList());
        return stockInfos;
    }

    @Override
    public List<StockInfo> amountSort() {
        List<StockInfo> stockInfos = stockInfoMapper.selectAll();
        if (stockInfos == null || stockInfos.size() <= 0){
            log.error("未查到股票基础数据列表");
            return new ArrayList<>();
        }
        stockInfos = stockInfos.stream()
                .filter(p -> p.getAmount() != null && !p.getAmount().isEmpty())
                .filter(p -> {
                    try {
                        Double.parseDouble(p.getAmount());
                        return true;
                    } catch (NumberFormatException e) {
                        return false;
                    }
                })
                .sorted(Comparator.comparingDouble(
                        (StockInfo p) -> Double.parseDouble(p.getAmount())).reversed()
                )
                .limit(30)
                .collect(Collectors.toList());
        return stockInfos;
    }

    @Override
    public JSONObject amountSortCon() {
        JSONObject jsonObject = new JSONObject();
        List<StockInfo> all = stockInfoMapper.selectAll();
        if (all == null || all.size() <= 0){
            log.error("未查到股票基础数据列表");
        }
        List<StockInfo> stockInfosAmout = all.stream()
                .filter(p -> p.getAmount() != null && !p.getAmount().isEmpty())
                .filter(p -> {
                    try {
                        Double.parseDouble(p.getAmount());
                        return true;
                    } catch (NumberFormatException e) {
                        return false;
                    }
                })
                .sorted(Comparator.comparingDouble(
                        (StockInfo p) -> Double.parseDouble(p.getAmount())).reversed()
                )
                .limit(25)
                .collect(Collectors.toList());


        int amoutSort = 1;
        StringBuilder amoutBuild = new StringBuilder();
        for (StockInfo stockInfo : stockInfosAmout) {
            if(StringUtils.isNotBlank(amoutBuild.toString())){
                amoutBuild.append(",");
            }
            amoutBuild.append(amoutSort + "." +stockInfo.getName());
            amoutSort++;
        }
        jsonObject.put("amoutBuild", amoutBuild);

        List<StockInfo> stockInfosVol = all.stream()
                .filter(p -> p.getVol() != null && !p.getAmount().isEmpty())
                .filter(p -> {
                    try {
                        Double.parseDouble(p.getVol());
                        return true;
                    } catch (NumberFormatException e) {
                        return false;
                    }
                })
                .sorted(Comparator.comparingDouble(
                        (StockInfo p) -> Double.parseDouble(p.getVol())).reversed()
                )
                .limit(25)
                .collect(Collectors.toList());
        int vodSort = 1;
        StringBuilder volBuild = new StringBuilder();
        for (StockInfo stockInfo : stockInfosVol) {
            if(StringUtils.isNotBlank(volBuild.toString())){
                volBuild.append(",");
            }
            volBuild.append(vodSort + "." + stockInfo.getName());
            vodSort++;
        }
        jsonObject.put("volBuild", volBuild);
        return jsonObject;

    }
}
